package com.nineclock.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.common.constant.NcConstant;
import com.nineclock.common.constant.SMSConstant;
import com.nineclock.common.enums.MessageTypeEnum;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.filter.CurrentUserHolder;
import com.nineclock.common.oss.OssClientUtils;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.system.dto.*;
import com.nineclock.system.mapper.*;
import com.nineclock.system.msg.MessageDTO;
import com.nineclock.system.pojo.*;
import com.nineclock.system.service.SysCompanyService;
import com.nineclock.system.service.SysCompanyUserService;
import com.nineclock.system.service.SysUserService;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;


import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class SysCompanyServiceImpl implements SysCompanyService {
    @Autowired(required = false)
    private SysCompanyMapper companyMapper;
    @Autowired
    private OssClientUtils ossClientUtils;
    @Autowired
    private SysCompanyUserMapper companyUserMapper;
    @Autowired
    private SysCompanyUserRoleMapper companyUserRoleMapper;
    @Autowired
    private SysRoleMapper roleMapper;
    @Autowired
    private SysCompanyUserService companyUserService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private SysUserService userService;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    /**
     * 根据用户ID获取关联的企业列表
     *
     * @param userId
     * @return
     */
    @Override
    public List<SysCompanyDTO> queryUserJoinCompany(Long userId) {
        //校验参数
        if (userId == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //根据用户id查询关联一夜列表
        List<SysCompany> sysCompanyList = companyMapper.queryUserJoinCompany(userId);
        if (CollectionUtils.isEmpty(sysCompanyList)) {
            throw new NcException(ResponseEnum.USER_NOT_JOIN_COMPANY);
        }
        //数据转换
        List<SysCompanyDTO> sysCompanyDTOList = BeanHelper.copyWithCollection(sysCompanyList, SysCompanyDTO.class);
        return sysCompanyDTOList;
    }

    /**
     * 查询当前登录用户的企业信息
     *
     * @return
     */
    @Override
    public SysCompanyDTO queryCompanyInfo() {
        // 获取当前登录用户id
        Long companyId = CurrentUserHolder.get().getCompanyId();
        // 根据id查询企业信息
        SysCompany sysCompany = companyMapper.selectById(companyId);
        if (sysCompany==null){
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }
        SysCompanyDTO companyDTO = BeanHelper.copyProperties(sysCompany, SysCompanyDTO.class);
        return companyDTO;
    }

    /**
     * 接口名称：企业管理: 上传图片
     * 接口路径：POST/sys/company/uploadOSS
     *
     * @param file
     */
    @Override
    public String uploadCompanyLogo(MultipartFile file) throws IOException {
        // 参数校验
        if(file == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        // 文件类型校验
        String contentType = file.getContentType();
        if(!NcConstant.ALLOWED_IMG_TYPES.contains(contentType)){
            throw new NcException(ResponseEnum.INVALID_FILE_TYPE);
        }

        // 文件大小校验
        if(file.getSize() > NcConstant.maxFileSize){
            throw new NcException(ResponseEnum.FILE_SIZE_EXCEED_MAX_LIMIT);
        }

        // 调用阿里云oss工具类上传文件
        String fileUrl = ossClientUtils.uploadFile(file.getOriginalFilename(), file.getInputStream());

        return fileUrl;
    }

    /**
     * 接口名称： 更新当前企业的基本信息
     * 接口路径：PUT/sys/company
     *
     * @param sysCompanyDTO
     */
    @Override
    public void updateCompanyInfo(SysCompanyDTO sysCompanyDTO) {
        // 参数校验
        if (sysCompanyDTO == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        // 获取当前登录用户所属企业id
        Long companyId = CurrentUserHolder.get().getCompanyId();

        // 更新企业信息
        SysCompany sysCompany = new SysCompany();
        sysCompany.setName(sysCompanyDTO.getName());
        sysCompany.setLogo(sysCompanyDTO.getLogo());
        sysCompany.setId(companyId);
        companyMapper.updateById(sysCompany);

        // 更新企业员工中的企业名称
        SysCompanyUser sysCompanyUser = new SysCompanyUser();
        sysCompanyUser.setCompanyName(sysCompanyDTO.getName());

        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUser::getCompanyId, companyId);
        companyUserMapper.update(sysCompanyUser, wrapper);
    }
    //更换管理员
    @Override
    public void changeSysAdmin(String code, Long userId) {
        //校验参数
        if (StringUtils.isEmpty(code) || userId==null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        // 根据员工id查询员工信息，得到手机号码
        SysCompanyUser companyUser = companyUserMapper.selectById(userId);
        // 取出redis中验证码和传入的验证码，进行比较
        String redisCode = (String) redisTemplate.opsForValue().get(SMSConstant.SMS_CHANGE_MANAGER_KEY_PREFIX + companyUser.getMobile());
        if(StringUtils.isEmpty(redisCode) || !redisCode.equals(code)){
            throw new NcException(ResponseEnum.INVALID_VERIFY_CODE);
        }
        //查询原来管理员id
        SysCompanyUserDTO currentAdmin = companyUserService.queryCurrentAdmin();
        //查询管理员角色
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRole::getCompanyId, currentAdmin.getCompanyId());
        wrapper.eq(SysRole::getRoleName, NcConstant.ADMIN_ROLE_SYS);
        SysRole sysRole = roleMapper.selectOne(wrapper);
        //更换管理员
        LambdaQueryWrapper<SysCompanyUserRole> updateWrapper = new LambdaQueryWrapper<>();
        updateWrapper.eq(SysCompanyUserRole::getCompanyUserId,currentAdmin.getId());
        updateWrapper.eq(SysCompanyUserRole::getRoleId,sysRole.getId());

        SysCompanyUserRole companyUserRole = new SysCompanyUserRole();
        companyUserRole.setCompanyUserId(userId);
        companyUserRoleMapper.update(companyUserRole,updateWrapper);

    }
    /**
     * @ApiOperation(value = "根据企业的关键字名称查询企业列表")
     * @GetMapping("/list")*/
    @Override
    public List<SysCompanyDTO> queryCompanyByName(String keyword) {
        LambdaQueryWrapper<SysCompany> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(SysCompany::getName,keyword);
        List<SysCompany> sysCompanyList = companyMapper.selectList(wrapper);

        return BeanHelper.copyWithCollection(sysCompanyList,SysCompanyDTO.class);
    }
    /**申请加入企业*/
    @Override
    public void applyJoinCompany(SysApplyJoinCompanyUserDTO sysApplyJoinCompanyUserDTO) {
        //校验参数
        if (sysApplyJoinCompanyUserDTO==null||sysApplyJoinCompanyUserDTO.getMobile()==null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        // 更新用户信息
        SysUserDTO sysUserDTO = userService.queryUser(sysApplyJoinCompanyUserDTO.getMobile());
        SysUser sysUser = new SysUser();
        sysUser.setId(sysUserDTO.getId());
        sysUser.setUsername(sysApplyJoinCompanyUserDTO.getUserName());
        sysUser.setEmail(sysApplyJoinCompanyUserDTO.getEmail());
        sysUser.setUpdateTime(new Date());
        sysUser.setLastLoginCompanyId(sysApplyJoinCompanyUserDTO.getCompanyId());
        userMapper.updateById(sysUser);
        // 新增员工信息
        SysCompanyUser sysCompanyUser = new SysCompanyUser();
        sysCompanyUser.setUserId(sysUser.getId());
        sysCompanyUser.setCompanyId(sysApplyJoinCompanyUserDTO.getCompanyId());
        sysCompanyUser.setCompanyName(sysApplyJoinCompanyUserDTO.getCompanyName());
        sysCompanyUser.setPost(sysApplyJoinCompanyUserDTO.getPost());
        sysCompanyUser.setEmail(sysApplyJoinCompanyUserDTO.getEmail());
        sysCompanyUser.setTimeEntry(new Date());
        sysCompanyUser.setRemark(sysApplyJoinCompanyUserDTO.getApplyReason());
        sysCompanyUser.setEnable((short)0); // 未审核
        sysCompanyUser.setCreateTime(new Date());
        sysCompanyUser.setUpdateTime(new Date());
        sysCompanyUser.setMobile(sysApplyJoinCompanyUserDTO.getMobile());
        sysCompanyUser.setUserName(sysApplyJoinCompanyUserDTO.getUserName());
        sysCompanyUser.setImageUrl(sysApplyJoinCompanyUserDTO.getImageUrl());
        companyUserMapper.insert(sysCompanyUser);

        // TODO 推送消息给管理员
        // 推送消息给管理员，发送消息至MQ，消息微服务接收消息
        // 定义消息内容
        MessageDTO messageDTO = new MessageDTO();
        messageDTO.setMessageType(MessageTypeEnum.COMPANY_APPLY.getType()); // 消息类型
        messageDTO.setCompanyId(sysCompanyUser.getCompanyId().toString()); // 公司id
        messageDTO.setTitle(MessageTypeEnum.COMPANY_APPLY.getTitle()); // 标题
        messageDTO.setContent(sysCompanyUser.getUserName() + " 申请加入企业，请及时审批"); // 内容
        messageDTO.setUseStatus(0); // 未读
        messageDTO.setAudience(MessageTypeEnum.COMPANY_APPLY.getAudience()); // 消息作用域

        // 获取当前企业主管理员
        SysCompanyUser mainAdmin = companyUserMapper.queryMainAdminCompanyUser(sysCompanyUser.getCompanyId());
        messageDTO.setTargets(Arrays.asList(mainAdmin.getMobile())); // 目标用户，即审批人

        messageDTO.setApproveStatue(0); // 未审核
        messageDTO.setApplyUserId(sysCompanyUser.getUserId()); // 申请用户ID
        messageDTO.setApplyUsername(sysCompanyUser.getUserName()); // 申请用户名称

        messageDTO.setApproveUserId(mainAdmin.getUserId()); // 审批用户id
        messageDTO.setApproveUsername(mainAdmin.getUserName()); // 审批用户名称

        // 发送消息，参数1-消息的主题:标签，参数2-消息内容（一般用json字符串）
        rocketMQTemplate.convertAndSend("messagePushTopic", JSON.toJSONString(messageDTO));
    }

    /**
     * 加入企业审核
     * @param allowedJoinCompanyUserDTO
     */
    @Override
    public void allowedJoinCompany(SysAllowedJoinCompanyUserDTO allowedJoinCompanyUserDTO) {
        if (allowedJoinCompanyUserDTO.getApproved()) {
            //根据企业id，申请人用户id查找员工信息
            LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
            wrapper.eq(SysCompanyUser::getUserId, allowedJoinCompanyUserDTO.getApplyUserId());
            SysCompanyUser sysCompanyUser = companyUserMapper.selectOne(wrapper);
            //更改员工信息
            sysCompanyUser.setEnable((short) 1);
            sysCompanyUser.setCreateTime(new Date());
            sysCompanyUser.setRemark(allowedJoinCompanyUserDTO.getRemark());
            companyUserMapper.selectById(sysCompanyUser);
            // 推送消息给管理员，发送消息至MQ，插入新的消息
            // 定义消息内容
            MessageDTO messageDTO = new MessageDTO();
            messageDTO.setMessageType(MessageTypeEnum.COMPANY_APPLY_PASS.getType());//消息类型
            messageDTO.setCompanyId(CurrentUserHolder.get().getCompanyId().toString());//公司id
            messageDTO.setTitle(MessageTypeEnum.COMPANY_APPLY_PASS.getTitle());//标题
            messageDTO.setContent(sysCompanyUser.getUserName()+"申请加入企业，已通过");//内容
            messageDTO.setUseStatus(0);//未读
            messageDTO.setAudience(MessageTypeEnum.COMPANY_APPLY_PASS.getAudience());//消息作用域
            messageDTO.setTargets(Arrays.asList(sysCompanyUser.getMobile()));//目标用户申请人
            messageDTO.setApproveStatue(1);//已申请
            messageDTO.setApplyUserId(sysCompanyUser.getUserId());//申请用户id
            messageDTO.setApplyUsername(sysCompanyUser.getUserName());//申请用户名称
            messageDTO.setApproveUserId(sysCompanyUser.getUserId());//审批用户id
            messageDTO.setApproveUsername(sysCompanyUser.getUserName());//审批用户名称

            //发送消息，查询新消息
            rocketMQTemplate.convertAndSend("messagePushTopic",JSON.toJSONString(messageDTO));
            // 发送消息，更新旧消息状态为审核通过，消息内容为消息id
            rocketMQTemplate.convertAndSend("allowedJoinCompanyTopic",allowedJoinCompanyUserDTO.getNotifyMsgId());
        }else {
            //删除申请人信息
            LambdaQueryWrapper<SysCompanyUser> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(SysCompanyUser::getCompanyId,CurrentUserHolder.get().getCompanyId());
            wrapper1.eq(SysCompanyUser::getUserId,allowedJoinCompanyUserDTO.getApplyUserId());
            companyUserMapper.delete(wrapper1);
        }
    }

}
